package com.am.client;

import com.am.client.object.ProcessMessage;
import com.am.client.object.SplitWord;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;

public class AM implements EntryPoint {

    private TextArea taInput;
    private TextArea taSplit;
    private TextArea taProcessing;
    private TextArea taOutput;
    private Label lblError;

    private static final String SPLIT_URL = GWT.getModuleBaseURL()
	    + "wordSplit?s=";
    private static final String PROCESS_URL = GWT.getModuleBaseURL()
	    + "amcore?w=";

    public void onModuleLoad() {
	RootPanel rootPanel = RootPanel.get();

	AbsolutePanel absolutePanel = new AbsolutePanel();
	rootPanel.add(absolutePanel, 2, 2);
	absolutePanel.setSize("782px", "596px");

	Label lblPleaseInputWord = new Label("Please input word or sentences:");
	absolutePanel.add(lblPleaseInputWord, 10, 10);
	lblPleaseInputWord.setWidth("198px");

	Label lblTheSplittedWords = new Label("The split words:");
	absolutePanel.add(lblTheSplittedWords, 10, 176);
	lblTheSplittedWords.setSize("287px", "26px");

	taInput = new TextArea();
	absolutePanel.add(taInput, 10, 38);
	taInput.setSize("298px", "87px");

	taSplit = new TextArea();
	absolutePanel.add(taSplit, 10, 195);
	taSplit.setSize("298px", "154px");

	Label lblProcessing = new Label("Processing:");
	absolutePanel.add(lblProcessing, 341, 10);
	lblProcessing.setSize("92px", "20px");

	taProcessing = new TextArea();
	absolutePanel.add(taProcessing, 341, 38);
	taProcessing.setSize("423px", "349px");

	Label lblOutput = new Label("Output:");
	absolutePanel.add(lblOutput, 10, 401);

	taOutput = new TextArea();
	absolutePanel.add(taOutput, 10, 427);
	taOutput.setSize("754px", "113px");

	lblError = new Label("");
	absolutePanel.add(lblError, 10, 554);
	lblError.setSize("762px", "32px");

	Button btnSplit = new Button("New button");
	btnSplit.addClickHandler(new ClickHandler() {

	    @Override
	    public void onClick(ClickEvent event) {
		startSplit();

	    }

	});
	btnSplit.setText("Split");
	absolutePanel.add(btnSplit, 165, 139);
	btnSplit.setSize("69px", "31px");

	Button btnClearInput = new Button("New button");
	btnClearInput.addClickHandler(new ClickHandler() {
	    public void onClick(ClickEvent event) {
		clearSplit();
	    }
	});
	btnClearInput.setText("Clear");
	absolutePanel.add(btnClearInput, 240, 139);
	btnClearInput.setSize("69px", "31px");

	Button btnStart = new Button("New button");
	btnStart.addClickHandler(new ClickHandler() {
	    public void onClick(ClickEvent event) {
		startProcess();
	    }
	});
	btnStart.setText("Start");
	absolutePanel.add(btnStart, 240, 363);
	btnStart.setSize("69px", "31px");
    }

    private void startSplit() {
	// split words and set taSplit
	String url = SPLIT_URL;
	url += taInput.getText();
	url = URL.encode(url);
	// Send request to server and catch any errors.
	RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);

	try {
	    Request request = builder.sendRequest(null, new RequestCallback() {
		public void onError(Request request, Throwable exception) {
		    requestError("Couldn't retrieve JSON");
		}

		public void onResponseReceived(Request request,
			Response response) {
		    if (200 == response.getStatusCode()) {
			updateSplitWords(response.getText());
		    } else {
			requestError("Couldn't retrieve JSON ("
				+ response.getStatusText() + ")");
		    }
		}
	    });
	} catch (RequestException e) {
	    requestError("Couldn't retrieve JSON");
	}
    }

    private void clearSplit() {
	taInput.setText("");
	taSplit.setText("");
	taProcessing.setText("");
	taOutput.setText("");
    }

    private void startProcess() {
	String ta = taSplit.getText();
	String[] taa = ta.split("\r\n");
	for (String tas : taa) {
	    String url = PROCESS_URL;
	    url += tas;
	    url = URL.encode(url);
	    // Send request to server and catch any errors.
	    RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);

	    try {
		Request request = builder.sendRequest(null,
			new RequestCallback() {
			    public void onError(Request request,
				    Throwable exception) {
				requestError("Couldn't retrieve JSON");
			    }

			    public void onResponseReceived(Request request,
				    Response response) {
				if (200 == response.getStatusCode()) {
				    updateProcessResults(response.getText());
				} else {
				    requestError("Couldn't retrieve JSON ("
					    + response.getStatusText() + ")");
				}
			    }
			});
	    } catch (RequestException e) {
		requestError("Couldn't retrieve JSON");
	    }
	}
    }

    public void requestError(String err) {
	lblError.setText(err);
    }

    public void updateSplitWords(String jsonText) {
	JsArray<SplitWord> words = asArrayOfSplitWord(jsonText);
	StringBuilder s = new StringBuilder();
	boolean first = true;
	for (int i = 0, len = words.length(); i < len; i++) {
	    SplitWord sw = words.get(i);
	    if (!first) {
		s.append("\r\n");
	    }
	    s.append(sw.getWord());
	    first = false;
	}
	taSplit.setText(s.toString());
    }

    public void updateProcessResults(String jsonText) {
	JsArray<ProcessMessage> msgs = asArrayOfProcessMessage(jsonText);
	StringBuilder s = new StringBuilder();
	StringBuilder l = new StringBuilder();
	boolean first = true;
	for (int i = 0, len = msgs.length(); i < len; i++) {
	    ProcessMessage sw = msgs.get(i);
	    if (!first) {
		s.append("\r\n");
	    }
	    String msg = sw.getMessage();
	    if(msg.startsWith("Cell Learned:")){
		l.append(msg.substring("Cell Learned:".length()));
	    }else{
		s.append(sw.getMessage());
	    }
	    first = false;
	}
	taProcessing.setText(s.toString());
	taOutput.setText(l.toString());
    }

    private final native JsArray<SplitWord> asArrayOfSplitWord(String json) /*-{
									    return eval(json);
									    }-*/;

    private final native JsArray<ProcessMessage> asArrayOfProcessMessage(String json) /*-{
			 								return eval(json);
			 								}-*/;
}
